package com.gitee.huanminabc.utils_common.multithreading.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 增强的简单锁，基于 ReentrantLock 封装，提供更丰富的功能和更好的异常处理。
 * 支持锁状态查询、条件变量、公平/非公平模式等特性。
 */
public class SimpleLock implements LockBase {
    
    private final ReentrantLock lock;
    
    /**
     * 创建非公平锁
     */
    public SimpleLock() {
        this(false);
    }
    
    /**
     * 创建指定公平性的锁
     * @param fair true表示公平锁，false表示非公平锁
     */
    public SimpleLock(boolean fair) {
        this.lock = new ReentrantLock(fair);
    }
    
    @Override
    public void lock() {
        lock.lock();
    }

    @Override
    public boolean tryLock() {
        return lock.tryLock();
    }

    @Override
    public boolean tryLock(long timeout, TimeUnit unit) {
        try {
            return lock.tryLock(timeout, unit);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            return false;
        }
    }

    @Override
    public void unlock() {
        // 其他线程非法持有不允许释放
        if (!lock.isHeldByCurrentThread()) {
            throw new IllegalStateException("当前线程尚未持有这个锁，不允许释放: " + lock);
        }
        lock.unlock();
    }
    
    /**
     * 获取锁的持有计数
     * @return 当前线程持有锁的次数
     */
    public int getHoldCount() {
        return lock.getHoldCount();
    }
    
    /**
     * 检查当前线程是否持有锁
     * @return true如果当前线程持有锁
     */
    public boolean isHeldByCurrentThread() {
        return lock.isHeldByCurrentThread();
    }
    
    /**
     * 检查锁是否被任何线程持有
     * @return true如果锁被持有
     */
    public boolean isLocked() {
        return lock.isLocked();
    }
    
    /**
     * 检查是否有线程在等待获取锁
     * @return true如果有线程在等待
     */
    public boolean hasQueuedThreads() {
        return lock.hasQueuedThreads();
    }
    
    /**
     * 获取等待获取锁的线程数量
     * @return 等待线程数量
     */
    public int getQueueLength() {
        return lock.getQueueLength();
    }
    
    /**
     * 检查指定线程是否在等待获取锁
     * @param thread 要检查的线程
     * @return true如果指定线程在等待
     */
    public boolean hasQueuedThread(Thread thread) {
        return lock.hasQueuedThread(thread);
    }
    
    /**
     * 创建条件变量
     * @return 条件变量
     */
    public Condition newCondition() {
        return lock.newCondition();
    }
    
    /**
     * 获取等待指定条件的线程数量
     * @param condition 条件变量
     * @return 等待线程数量
     */
    public int getWaitQueueLength(Condition condition) {
        return lock.getWaitQueueLength(condition);
    }
    
    /**
     * 检查是否有线程在等待指定条件
     * @param condition 条件变量
     * @return true如果有线程在等待
     */
    public boolean hasWaiters(Condition condition) {
        return lock.hasWaiters(condition);
    }
    
    /**
     * 获取锁的字符串表示
     * @return 锁的详细信息
     */
    @Override
    public String toString() {
        return "SimpleLock{" +
                "isLocked=" + isLocked() +
                ", isHeldByCurrentThread=" + isHeldByCurrentThread() +
                ", holdCount=" + getHoldCount() +
                ", queueLength=" + getQueueLength() +
                ", fair=" + lock.isFair() +
                '}';
    }
}
